package com.harvest.scientific.ladder.ext

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.ContextWrapper
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.drawable.Drawable
import android.media.MediaMetadataRetriever
import android.os.Build
import android.text.TextUtils
import android.util.Log
import android.view.View
import android.widget.ImageView
import androidx.databinding.BindingAdapter
import com.bumptech.glide.Glide
import com.bumptech.glide.RequestBuilder
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
import com.bumptech.glide.load.resource.bitmap.*
import com.bumptech.glide.load.resource.bitmap.VideoDecoder.FRAME_OPTION
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.SimpleTarget
import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.transition.Transition
import java.security.MessageDigest

fun ImageView.loadUrl(url: String?) {
    if (isActivityDestroyed(context) || TextUtils.isEmpty(url)) return
    Glide.with(context).load(url).into(this)
}

fun ImageView.loadUrl(res: Int) {
    if (isActivityDestroyed(context)) return
    Glide.with(context).load(res).into(this)
}

fun ImageView.loadLocalPath(path: String, corner: Int = 0, skipDiskCache: Boolean = false) {
    if (isActivityDestroyed(context) || TextUtils.isEmpty(path)) return
    val transform = if (corner > 0) RequestOptions()
        .transform(CenterCrop(), RoundedCorners(corner)) else null

    Glide.with(context)
        .load("file://$path")
        .also { if (transform != null) it.apply(transform) }
        .dontAnimate()
        .also {
            if (skipDiskCache) it.diskCacheStrategy(DiskCacheStrategy.NONE)
        }
        .into(this)
}

/**
 * 加载视频第一帧图片
 */
fun ImageView.localSnapshotFromVideo(path: String, frameTimeMicros: Long = 0, skipDiskCache: Boolean = false) {
    if (isActivityDestroyed(context) || TextUtils.isEmpty(path)) return
    val transform = RequestOptions.frameOf(frameTimeMicros)
        .set(FRAME_OPTION, MediaMetadataRetriever.OPTION_CLOSEST)
        .transform(CenterCrop())

    Glide.with(context)
        .load("file://$path")
        .also { if (transform != null) it.apply(transform) }
        .dontAnimate()
        .also {
            if (skipDiskCache) it.diskCacheStrategy(DiskCacheStrategy.NONE)
        }
        .into(this)
}

fun isActivityDestroyed(context: Context?): Boolean {
    val activity: Activity? = findActivity(context)
    return if (activity != null) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            activity.isDestroyed || activity.isFinishing
        } else activity.isFinishing
    } else true
}

fun findActivity(context: Context?): Activity? {
    //怎么判断context 是不是activity 类型的
    if (context is Activity) {
        return context
    } else if (context is ContextWrapper) {
        return findActivity(context.baseContext)
    }
    return null
}
fun ImageView.loadUrl(url: String?, res: Int) {
    if (isActivityDestroyed(context)) return
    Glide.with(context).load(url)
        .error(res)
        .placeholder(res)
        .fallback(res)
        .into(this)
}

fun ImageView.loadUrlByCenterCorp(url: String?) {
    if (isActivityDestroyed(context) || TextUtils.isEmpty(url)) return
    Glide.with(context).load(url)
        .centerCrop()
        .into(this)
}

fun ImageView.loadUrlByCenterCorp(url: String?, res: Int) {
    if (isActivityDestroyed(context)) return
    Glide.with(context).load(url)
        .error(res)
        .placeholder(res)
        .fallback(res)
        .centerCrop()
        .into(this)
}

fun ImageView.loadUrl(url: String?, placeHolder: Int, errorHolder: Int) {
    if (isActivityDestroyed(context) || TextUtils.isEmpty(url)) return
    var glide: RequestBuilder<Drawable> = Glide.with(context).load(url)
    if (errorHolder != 0) {
        glide = glide.error(errorHolder)
    }
    if (placeHolder != 0) {
        glide = glide.placeholder(placeHolder)
    }
    glide.fallback(errorHolder)
        .into(this)
}

fun ImageView.loadUrl(url: String?, callback: (Drawable) -> Unit) {
    //you cannot load url from destory activity
    if (isActivityDestroyed(context) || TextUtils.isEmpty(url)) return
    Glide.with(context).load(url).into(object : SimpleTarget<Drawable>() {
        override fun onResourceReady(resource: Drawable, transition: Transition<in Drawable>?) {
            callback(resource)
        }
    })
}

/**
 * 加载视频url的封面图
 * 注意是videoUrl
 */
@SuppressLint("CheckResult")
fun ImageView.loadVideoCover(videoUrl: String?, position: Int = 1) {
    if (isActivityDestroyed(context) || TextUtils.isEmpty(videoUrl)) return
    val options = RequestOptions.frameOf(position * 1000L * 1000).apply {
        set(VideoDecoder.FRAME_OPTION, MediaMetadataRetriever.OPTION_CLOSEST)

        transform(object : BitmapTransformation() {
            override fun updateDiskCacheKey(messageDigest: MessageDigest) {
                messageDigest.update((getPackageName() + "Transform").toByteArray())
            }

            override fun transform(
                pool: BitmapPool,
                toTransform: Bitmap,
                outWidth: Int,
                outHeight: Int
            ): Bitmap {
                return toTransform
            }

        })
    }

    Glide.with(context).load(videoUrl).apply(options).into(this)
}

fun ImageView.loadCircle(circleUrl: String?, placeholder: Int = 0) {
    if (isActivityDestroyed(context)) return
    var builder = Glide.with(this).load(circleUrl)
    if (placeholder != 0) {
        builder = builder.error(placeholder)
            .placeholder(placeholder)
    }
    builder.transform(CircleCrop()).into(this)
}
fun ImageView.loadCorner(url: String?, corner: Int, placeholder: Int = 0, isCenterCrop: Boolean = true){
    loadCorner2(url, corner, placeholder, placeholder, isCenterCrop)
}
//巨坑，glide 的 图片裁剪 和 imageview scaleType 有冲突。 centerCrop .
fun ImageView.loadCorner2(url: String?, corner: Int, placeholder: Int = 0, errorHolder: Int = 0, isCenterCrop: Boolean = true) {
    if (isActivityDestroyed(context)) return
    var transform = if (corner > 0) RequestOptions()
        .also {
            if (isCenterCrop) {
                it.transform(CenterCrop(), RoundedCorners(corner))
            } else {
                it.transform(RoundedCorners(corner))
            }

        }
    else RequestOptions().also { it.transform(CenterCrop()) }
    if (placeholder != 0) {
        transform = transform.placeholder(placeholder)
    }
    if(errorHolder != 0) {
        transform = transform.error(errorHolder)
    }
    val listener = object :RequestListener<Drawable> {

        override fun onLoadFailed(
            e: GlideException?,
            model: Any?,
            target: Target<Drawable>,
            isFirstResource: Boolean
        ): Boolean {
            Log.i("ImageView" , "load image failed e: ${e?.message}, isFirstResource: $isFirstResource, url: $url")
            return false
        }

        override fun onResourceReady(
            resource: Drawable,
            model: Any,
            target: Target<Drawable>?,
            dataSource: DataSource,
            isFirstResource: Boolean
        ): Boolean {
            return false
        }
    }

    if (corner > 0) {
        Glide.with(this)
            .load(url)
            .apply(transform)
            .thumbnail(loadTransform(this, placeholder, errorHolder, corner))
            .addListener(listener)
            .into(this)
    } else {
        Glide.with(this)
            .load(url)
            .apply(transform)
            .addListener(listener)
            .into(this)
    }
}

private fun loadTransform(
    view: View,
    placeholderId: Int,
    errorHolder: Int,
    corner: Int
): RequestBuilder<Drawable?> {
    return Glide.with(view)
        .load(placeholderId)
        .error(errorHolder)
        .apply(RequestOptions().centerCrop().transform(RoundedCorners(corner)))
}

fun ImageView.loadCircleBorder(
    url: String,
    borderWidth: Float = 0f,
    borderColor: Int = Color.WHITE
) {
    if (isActivityDestroyed(context) || TextUtils.isEmpty(url)) return
    Glide.with(this).load(url).transform(CircleBorderTransform(borderWidth, borderColor))
        .into(this)

}

class CircleBorderTransform(private val borderWidth: Float, borderColor: Int) : CircleCrop() {
    private var borderPaint: Paint = Paint(Paint.ANTI_ALIAS_FLAG)

    init {
        borderPaint.color = borderColor
        borderPaint.style = Paint.Style.STROKE
        borderPaint.strokeWidth = borderWidth
    }

    override fun transform(
        pool: BitmapPool,
        toTransform: Bitmap,
        outWidth: Int,
        outHeight: Int
    ): Bitmap {
        val transform = super.transform(pool, toTransform, outWidth, outHeight)
        val canvas = Canvas(transform)

        val halfWidth = outWidth / 2.toFloat()
        val halfHeight = outHeight / 2.toFloat()


        canvas.drawCircle(
            halfWidth,
            halfHeight,
            halfWidth.coerceAtMost(halfHeight) - borderWidth / 2,
            borderPaint
        )

        canvas.setBitmap(null)

        return transform
    }
}
